package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.AlbumMapper;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.BrandMapper;
import cn.tedu.csmall.product.mapper.SpuMapper;
import cn.tedu.csmall.product.pojo.dto.AlbumAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.BrandAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.BrandUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Album;
import cn.tedu.csmall.product.pojo.entity.Brand;
import cn.tedu.csmall.product.pojo.entity.BrandCategory;
import cn.tedu.csmall.product.pojo.vo.AlbumListItemVO;
import cn.tedu.csmall.product.pojo.vo.AlbumStandardVO;
import cn.tedu.csmall.product.pojo.vo.BrandListItemVO;
import cn.tedu.csmall.product.pojo.vo.BrandStandardVO;
import cn.tedu.csmall.product.repo.IBrandRedisRepository;
import cn.tedu.csmall.product.service.IAlbumService;
import cn.tedu.csmall.product.service.IBrandService;
import cn.tedu.csmall.product.web.ServiceCode;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
@Data
public class BrandServiceImpl implements IBrandService {

    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private BrandCategoryMapper brandCategoryMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private IBrandRedisRepository brandRedisRepository;
    public BrandServiceImpl() {
        log.debug("创建业务对象: BrandServiceImpl");
    }

    @Override
    public void addNew(BrandAddNewDTO brandAddNewDTO) {
        log.debug("开始处理添加品牌业务,参数: {}", brandAddNewDTO);
        //从参数对象中获取品牌名称
        String brandName = brandAddNewDTO.getName();
        //
        int countByName = brandMapper.countByName(brandName);
        log.debug("尝试添加的品牌名称是：{}，在数据库中此名称的品牌数量为：{}", brandName, countByName);
        if(countByName>0){
            //是: 品牌名称已经被占用,添加品牌失败,抛出异常
            String message = "添加品牌失败，品牌名称【" + brandAddNewDTO.getName() + "】已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //否: 品牌名称没有被占用, 则向品牌表中插入数据
        log.debug("品牌名称没有被占用,将向品牌表中插入数据");
        Brand brand = new Brand();
        //album.getName().toLowerCase();
        BeanUtils.copyProperties(brandAddNewDTO,brand);
        log.debug("即将插入品牌数据:{}",brand);
        brandMapper.insert(brand);
        log.debug("插入品牌数据完成");
        }

        @Override
        public void delete(Long id){
            log.debug("开始处理[根据id删除品牌]的业务,参数: {}", id);
            // 调用Mapper对象的getStandardById()执行查询
            BrandStandardVO queryResult = brandMapper.getStandardById(id);
            if(queryResult == null){
                // 是：无此id对应的数据，将不允许执行删除操作，则抛出异常
                String message = "删除品牌失败,尝试访问的数据不存在! ";
                log.debug(message);
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
            }
            {
                // 检查是否存在品牌类别（brandCategory）关联到此品牌，如果存在，则不允许删除
                int count = brandCategoryMapper.countByBrandId(id);
                if (count > 0) {
                    String message = "删除品牌失败,此品牌存在关联的品牌类别数据! ";
                    log.debug(message);
                    throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
                }
            }
            {
                // 检查是否存在SPU关联到此品牌，如果存在，则不允许删除
                int count = spuMapper.countByBrandId(id);
                if(count > 0){
                    String message = "删除品牌失败,此相册存在关联的SPU数据! ";
                    log.debug(message);
                    throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
                }
            }
            // 调用Mapper对象的deleteById()方法执行删除
            log.debug("即将执行删除,参数:{}", id);
            brandMapper.deleteById(id);
        }

    @Override
    public void updateInfoById(Long id, BrandUpdateDTO brandUpdateDTO) {
        log.debug("开始处理【修改品牌详情】的业务，参数：{}", id);
        // 调用Mapper对象的getDetailsById()方法执行查询
        BrandStandardVO queryResult = brandMapper.getStandardById(id);
        // 判断查询结果是否为null
        if (queryResult == null) {
            // 是：此id对应的数据不存在，则抛出异常(ERR_NOT_FOUND)
            String message = "修改品牌详情失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        Brand brand = new Brand();
        BeanUtils.copyProperties(brandUpdateDTO, brand);
        brand.setId(id);

        // 修改数据
        log.debug("即将修改数据：{}", brand);
        int rows = brandMapper.updateById(brand);
        if (rows != 1) {
            String message = "修改品牌详情失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }


    @Override
    public BrandStandardVO getStandardById(Long id) {

        log.debug("开始处理[根据id查询品牌详情]的业务,参数: {}", id);
        // 根据id从缓存中获取数据
        // 判断获取到的结果是否不为null
        // 是: 直接返回

        // 无缓存数据, 从数据库中查找数据
        //  判断查询到的结果是否为null
        //  是: 抛出异常

        //  将查询结果写入到缓存, 并返回

        BrandStandardVO brand = brandRedisRepository.get(id);
        if (brand != null) {
            log.debug("命中缓存, 即将返回: {}", brand);
            return brand;
        }

        // 无缓存数据, 从数据库中查找数据
        log.debug("未命中缓存, 即将从数据库中查找数据");
        brand = brandMapper.getStandardById(id);
        //判断查找到的结果是否为null
        if (brand == null) {
            //是: 抛出异常
            String message = "获取品牌详情失败, 尝试访问的数据不存在! ";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 将查询结果写入到缓存, 并返回
        log.debug("从数据库查询到有效结果, 将查询结果存入到Redis: {}", brand);
        brandRedisRepository.save(brand);
        log.debug("返回结果: {}", brand);
        return brand;
    }
//        // 调用Mapper对象的getStandardById()执行查询
//        BrandStandardVO queryResult = brandMapper.getStandardById(id);
//        if(queryResult == null){
//            // 是：无此id对应的数据，将不允许执行查询操作，则抛出异常
//            String message = "查询品牌详情失败,尝试访问的数据不存在! ";
//            log.debug(message);
//            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
//        }
//        // 调用Mapper对象的getStandardById()方法执行查询
//        return queryResult;
//    }

    @Override
    public List<BrandListItemVO> list() {
        log.debug("开始处理[查询品牌列表]的业务,无参数");
        List<BrandListItemVO> list = brandMapper.list();
//        brandRedisRepository.save(list);
        return list;
        //return brandRedisRepository.list();
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    @Override
    public void rebuildCache() {
        log.debug("CachePreload.run()");

        log.debug("准备删除Redis缓存中的品牌数据……");
        brandRedisRepository.deleteAll();
        log.debug("删除Redis缓存中的品牌数据，完成！");

        log.debug("准备从数据库中读取品牌列表……");
        List<BrandListItemVO> list = brandMapper.list();
        log.debug("从数据库中读取品牌列表，完成！");

        log.debug("准备将品牌列表写入到Redis缓存……");
        brandRedisRepository.save(list);
        log.debug("将品牌列表写入到Redis缓存，完成！");
    }

    private void updateEnableById(Long id, Integer enable) {
        String[] tips = {"禁用", "启用"};
        log.debug("开始处理【{}品牌】的业务，参数：{}", tips[enable], id);

        // 判断参数id是否为1
        if (id == 1) {
            String message = tips[enable] + "品牌失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 检查尝试访问的数据是否存在
        BrandStandardVO queryResult = brandMapper.getStandardById(id);
        if (queryResult == null) {
            String message = tips[enable] + "品牌失败，尝试访问的数据不存在！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 判断状态是否冲突（当前已经是目标状态）
        if (queryResult.getEnable().equals(enable)) {
            String message = tips[enable] + "品牌失败，品牌账号已经处于" + tips[enable] + "状态！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 准备执行更新
        Brand brand = new Brand();
        brand.setId(id);
        brand.setEnable(enable);
        int rows = brandMapper.update(brand);
        if (rows != 1) {
            String message = tips[enable] + "品牌失败，服务器忙，请稍后再次尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE, message);
        }
    }
}

